package com.lingyi.framework.web.service;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.lingyi.common.config.WechatConfig;
import com.lingyi.common.constant.CacheConstants;
import com.lingyi.common.core.redis.RedisCache;
import com.lingyi.common.utils.RestTemplateUtil;
import com.lingyi.common.utils.StringUtils;
import com.lingyi.system.domain.Message;
import lombok.RequiredArgsConstructor;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @PackageName: com.lingyi.framework.web.service
 * @ClassName: WechatService
 * @Description:
 * @Author: czl
 * @Date: 2025/4/19 17:12
 */
@Service
@RequiredArgsConstructor
public class WechatService {

    private static Logger logger = LoggerFactory.getLogger(WechatService.class);

    private final WechatConfig wechatConfig;
    private final RestTemplateUtil restTemplateUtil;
    private final RedisCache redisCache;
    private final OkHttpClient okHttpClient;

    public String getAccessToken() {
        String accessToken = redisCache.getCacheObject(CacheConstants.ACCESS_TOKEN_KEY);
        if (ObjectUtil.isNull(accessToken)) {
            accessToken = getRequestAccessToken();
            if (StringUtils.isNull(accessToken)) {
                throw new RuntimeException("获取access_toke失败");
            }
            redisCache.setCacheObject(CacheConstants.ACCESS_TOKEN_KEY, accessToken, 1, TimeUnit.MINUTES);
        }
        return accessToken;
    }

    public String getRequestAccessToken() {
        ResponseEntity<String> exchange = restTemplateUtil.sendGetRequest(wechatConfig.getAccessTokenUrl());
        if (exchange.getStatusCode().is2xxSuccessful()) {
            String body = exchange.getBody();
            JSONObject jsonObject = JSON.parseObject(body);
            return jsonObject.getString("access_token");
        }
        return null;
    }

    public String uploadMaterial(InputStream inputStream, String type, String fileName) throws IOException {

        String uploadUrl = String.format(wechatConfig.getUploadMaterialUrl(), getAccessToken(), type);

        try (InputStream in = inputStream) {

            MediaType mediaType = MediaType.parse(type);
            RequestBody requestBody = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("media", fileName, RequestBody.create(mediaType, Objects.requireNonNull(inputStreamToBytes(in))))
                    .build();

            Request request = new Request.Builder()
                    .url(uploadUrl)
                    .post(requestBody)
                    .build();

            try (Response response = okHttpClient.newCall(request).execute()) {
                if (response.isSuccessful()) {
                    String responseBody = Objects.requireNonNull(response.body()).string();
                    logger.info("上传成功: {}", responseBody);
                    JSONObject result = JSONObject.parseObject(responseBody);
                    return result.getString("media_id");
                } else {
                    logger.error("请求失败：{}-{}", response.code(), response.message());
                    throw new IOException("请求失败：" + response.code() + "-" + response.message());
                }
            }
        } catch (IOException e) {
            logger.error("上传材料时发生错误: {}", e.getMessage(), e);
            throw e;
        }

//        String uploadUrl = String.format(wechatConfig.getUploadMaterialUrl(), getAccessToken(), type);
//
//        OkHttpClient client = new OkHttpClient();
//        RequestBody requestBody = new MultipartBody.Builder()
//                .setType(MultipartBody.FORM)
//                .addFormDataPart("media", fileName,
//                        RequestBody.create(MediaType.parse(type), Objects.requireNonNull(inputStreamToBytes(inputStream))))
//                .build();
//        Request request = new Request.Builder()
//                .url(uploadUrl)
//                .post(requestBody)
//                .build();
//        Response response = client.newCall(request).execute();
//        String responseBody = "";
//        if (response.isSuccessful()) {
//            responseBody = Objects.requireNonNull(response.body()).string();
//            System.out.println(responseBody);
//        } else {
//            logger.error("请求失败：{}-{}", response.code(), response.message());
//        }
//        response.close();
//        // 解析返回结果，获取上传后的媒体 ID
//        JSONObject result = JSONObject.parseObject(responseBody);
//        System.out.println(result.get("media_id").toString());
//        return result.get("media_id").toString();
    }

    private static byte[] inputStreamToBytes(InputStream inputStream) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, bytesRead);
        }
        byteArrayOutputStream.close();
        return byteArrayOutputStream.toByteArray();
    }

    public String sending(String openId, Message message) {
        String requestUrl = String.format(wechatConfig.getCustomSendUrl(), getAccessToken());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(org.springframework.http.MediaType.APPLICATION_JSON);

        HashMap<String, Object> params = new HashMap<>();
        params.put("touser", openId);
        params.put("msgtype", message.getType());

        switch (message.getType()) {
            case "image":
                Map<String, Object> imageParams = new HashMap<>();
                imageParams.put("media_id", message.getContext());
                params.put(message.getType(), imageParams);
                break;
            case "video":
                Map<String, Object> mediaParams = new HashMap<>();
                mediaParams.put("media_id", message.getContext());
                mediaParams.put("title", message.getTitle());
                mediaParams.put("description", message.getDescription());
                params.put(message.getType(), mediaParams);
                break;
            default:
                Map<String, Object> contentParams = new HashMap<>();
                contentParams.put("content", message.getContext());
                params.put(message.getType(), contentParams);
                break;
        }

        ResponseEntity<String> stringResponseEntity = restTemplateUtil.sendPostRequest(requestUrl, JSON.toJSONString(params));
        if (stringResponseEntity.getStatusCode().is2xxSuccessful()) {
            String body = stringResponseEntity.getBody();
            logger.info("openId:{}发送消息成功:{}", openId, body);
            return body;
        } else {
            logger.error("openId:{} 发送消息失败: {}", openId, stringResponseEntity.getBody());
            return "";
        }
    }
}
